package com.ruoyi.common.utils;

import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * 多源金融数据API工具类 - 替代fx678 API
 * 提供外汇、黄金、商品等实时数据
 */
@Slf4j
@Component
public class AllTickApiUtil {

    // UniRateAPI - 主要数据源（免费无限制，593种货币）
    private static final String UNI_RATE_API_URL = "https://api.unirateapi.com/api/rates";
    private static final String UNI_RATE_API_KEY = "olF1H0BQqJRd0vw5p9hq3RUIaqSCZWcl9uKHBLzhSXtw5rRZOrL8djQsL53iTuLc";
    
    // FreeForexAPI - 外汇数据（免费无限制，8个主要货币对）
    private static final String FREE_FOREX_API_URL = "https://www.freeforexapi.com/api/live";
    
    // Live-Rates.com - 备用数据源
    private static final String LIVE_RATES_URL = "https://www.live-rates.com/rates";
    
    /**
     * 测试UniRateAPI连接
     * @return 测试结果
     */
    public static String testUniRateApiConnection() {
        try {
            String result = HttpRequest.get(UNI_RATE_API_URL + "?from=USD&api_key=" + UNI_RATE_API_KEY)
                    .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
                    .header("Authorization", "Bearer " + UNI_RATE_API_KEY)
                    .timeout(10000)
                    .execute().body();
            
            //log.info("UniRateAPI连接测试成功，返回数据: {}", result.substring(0, Math.min(200, result.length())));
            return result;
        } catch (Exception e) {
            log.error("UniRateAPI连接测试失败: {}", e.getMessage());
            return "连接失败: " + e.getMessage();
        }
    }
    
    /**
     * 获取外汇实时报价
     * @param symbol 货币对符号 (如: EURUSD, GBPUSD)
     * @return 价格数据JSON字符串
     */
    public static String getForexQuote(String symbol) {
        // 1. 尝试UniRateAPI（免费无限制）
        try {
            String result = HttpRequest.get(UNI_RATE_API_URL + "?from=USD&api_key=" + UNI_RATE_API_KEY)
                    .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
                    .header("Authorization", "Bearer " + UNI_RATE_API_KEY)
                    .timeout(10000)
                    .execute().body();
            
            //log.info("UniRateAPI外汇数据获取成功: {}", symbol);
            return convertUniRateApiToFx678Format(result, symbol);
            
        } catch (Exception e) {
            log.error("UniRateAPI失败，尝试FreeForexAPI: {}", e.getMessage());
        }
        
        // 2. 尝试FreeForexAPI（免费无限制，主要货币对）
        try {
            String pairs = convertToFreeForexApiSymbol(symbol);
            String result = HttpRequest.get(FREE_FOREX_API_URL + "?pairs=" + pairs)
                    .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
                    .timeout(10000)
                    .execute().body();
            
            //log.info("FreeForexAPI外汇数据获取成功: {}", symbol);
            return convertFreeForexApiToFx678Format(result, symbol);
            
        } catch (Exception e) {
            log.error("FreeForexAPI失败，尝试备用数据源: {}", e.getMessage());
        }
        
        // 2. 备用：Live-Rates API
        try {
            String result = HttpRequest.get(LIVE_RATES_URL)
                    .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
                    .timeout(10000)
                    .execute().body();
            
            //log.info("Live-Rates外汇数据获取成功: {}", symbol);
            return convertLiveRatesToFx678Format(result, symbol);
            
        } catch (Exception e) {
            log.error("所有外汇API都失败，使用模拟数据: {}", e.getMessage());
            return "{}";
        }
    }
    
    /**
     * 获取黄金实时报价
     * @param symbol 黄金符号 (如: GOLD, SILVER)
     * @return 价格数据JSON字符串
     */
    public static String getMetalQuote(String symbol) {
        // 1. 尝试UniRateAPI（免费无限制，支持贵金属）
        try {
            String result = HttpRequest.get(UNI_RATE_API_URL + "?from=USD&api_key=" + UNI_RATE_API_KEY)
                    .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
                    .header("Authorization", "Bearer " + UNI_RATE_API_KEY)
                    .timeout(10000)
                    .execute().body();
            
            //log.info("UniRateAPI黄金数据获取成功: {}", symbol);
            return convertUniRateApiToFx678Format(result, symbol);
            
        } catch (Exception e) {
            log.error("UniRateAPI失败，尝试备用数据源: {}", e.getMessage());
        }
        
        // 3. 备用：Live-Rates API
        try {
            String result = HttpRequest.get(LIVE_RATES_URL)
                    .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
                    .timeout(10000)
                    .execute().body();
            
            //log.info("Live-Rates黄金数据获取成功: {}", symbol);
            return convertLiveRatesToFx678Format(result, symbol);
            
        } catch (Exception e) {
            log.error("所有黄金API都失败，使用模拟数据: {}", e.getMessage());
            return "{}";
        }
    }
    
    /**
     * 获取商品实时报价
     * @param symbol 商品符号 (如: OIL, GAS)
     * @return 价格数据JSON字符串
     */
    public static String getCommodityQuote(String symbol) {
        try {
            // 直接使用Live-Rates API获取商品数据
            String result = HttpRequest.get(LIVE_RATES_URL)
                    .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
                    .timeout(10000)
                    .execute().body();
            
            //log.info("Live-Rates商品数据获取成功: {}", symbol);
            return convertLiveRatesToFx678Format(result, symbol);
            
        } catch (Exception e) {
            log.error("Live-Rates商品数据获取失败，使用模拟数据: {}", e.getMessage());
            return "{}";
        }
    }
    

    
    /**
     * 将Live-Rates数据格式转换为fx678兼容格式（JSONArray格式）
     */
    private static String convertLiveRatesToFx678Format(String liveRatesData, String symbol) {
        try {
            // Live-Rates返回的是JSON数组格式
            if (liveRatesData.startsWith("[")) {
                JSONObject[] rates = JSONUtil.toBean(liveRatesData, JSONObject[].class);
                
                // 首先尝试精确匹配
                for (JSONObject rate : rates) {
                    String currency = rate.getStr("currency", "");
                    if (matchSymbol(symbol, currency)) {
                        // 构建fx678兼容的JSONArray格式
                        JSONObject fx678Format = new JSONObject();
                        
                        // 获取价格数据
                        String currentPrice = rate.getStr("close", rate.getStr("bid", "0"));
                        String openPrice = rate.getStr("open", currentPrice);
                        String highPrice = rate.getStr("high", currentPrice);
                        String lowPrice = rate.getStr("low", currentPrice);
                        long timestamp = rate.getLong("timestamp", System.currentTimeMillis());
                        
                        // 构建JSONArray格式的数据 (模拟fx678的t,h,l,o,c格式)
                        JSONArray timeArray = new JSONArray();
                        JSONArray highArray = new JSONArray();
                        JSONArray lowArray = new JSONArray();
                        JSONArray openArray = new JSONArray();
                        JSONArray closeArray = new JSONArray();
                        JSONArray volumeArray = new JSONArray();
                        
                        // 添加当前数据点
                        timeArray.add(timestamp);
                        highArray.add(Double.parseDouble(highPrice));
                        lowArray.add(Double.parseDouble(lowPrice));
                        openArray.add(Double.parseDouble(openPrice));
                        closeArray.add(Double.parseDouble(currentPrice));
                        volumeArray.add(0);
                        
                        // 构建最终的数据结构
                        fx678Format.put("t", timeArray);
                        fx678Format.put("h", highArray);
                        fx678Format.put("l", lowArray);
                        fx678Format.put("o", openArray);
                        fx678Format.put("c", closeArray);
                        fx678Format.put("v", volumeArray);
                        fx678Format.put("symbol", symbol);
                        fx678Format.put("source", "LiveRates");
                        
                        //log.info("找到匹配数据: {} -> {}, 价格: {}", symbol, currency, currentPrice);
                        return fx678Format.toString();
                    }
                }
            }
            
        } catch (Exception e) {
            log.error("Live-Rates数据格式转换失败: {}", e.getMessage());
        }
        
        log.error("未找到匹配的数据，使用模拟数据: {}", symbol);
        return "{}";
    }
    
    /**
     * 符号匹配逻辑
     */
    private static boolean matchSymbol(String requestSymbol, String dataSymbol) {
        // 移除斜杠和特殊字符进行比较
        String cleanRequest = requestSymbol.replaceAll("[/\\-_]", "").toUpperCase();
        String cleanData = dataSymbol.replaceAll("[/\\-_]", "").toUpperCase();
        
        // 直接匹配
        if (cleanRequest.equals(cleanData)) {
            return true;
        }
        
        // 外汇对匹配 (如 EURUSD 匹配 EUR/USD)
        if (cleanRequest.length() == 6 && cleanData.length() == 6) {
            return cleanRequest.equals(cleanData);
        }
        
        // 黄金符号匹配
        if ((cleanRequest.equals("GOLD") || cleanRequest.equals("XAU")) && 
            (cleanData.equals("GOLD") || cleanData.equals("XAUUSD"))) {
            return true;
        }
        
        // 白银符号匹配
        if ((cleanRequest.equals("SILVER") || cleanRequest.equals("XAG")) && 
            (cleanData.equals("SILVER") || cleanData.equals("XAGUSD"))) {
            return true;
        }
        
        // 原油符号匹配
        if ((cleanRequest.equals("OIL") || cleanRequest.equals("CRUDE")) && 
            (cleanData.equals("CRUDEOIL") || cleanData.equals("USOIL"))) {
            return true;
        }
        
        // 天然气符号匹配
        if ((cleanRequest.equals("GAS") || cleanRequest.equals("NGAS")) && 
            (cleanData.equals("NATURALGAS") || cleanData.equals("NGAS"))) {
            return true;
        }
        
        return false;
    }
    

    /**
     * 映射到Gold-API符号
     */
    private static String mapToGoldApiSymbol(String symbol) {
        switch (symbol.toUpperCase()) {
            case "GOLD":
            case "XAU":
            case "XAUUSD": return "XAU";
            case "SILVER":
            case "XAG":
            case "XAGUSD": return "XAG";
            default: return "XAU";
        }
    }
    
    /**
     * 转换UniRateAPI数据格式
     */
    private static String convertUniRateApiToFx678Format(String uniRateApiData, String symbol) {
        try {
            JSONObject json = JSONUtil.parseObj(uniRateApiData);
            if (json.containsKey("rates")) {
                JSONObject rates = json.getJSONObject("rates");
                String targetSymbol = convertToUniRateApiSymbol(symbol);
                
                if (rates.containsKey(targetSymbol)) {
                    double rate = rates.getDouble(targetSymbol);
                    
                    // 对于贵金属，UniRateAPI返回的是"1美元能买到多少盎司"
                    // 我们需要取倒数得到"1盎司值多少美元"
                    if (isPreciousMetal(symbol)) {
                        rate = 1.0 / rate;
                        //log.info("贵金属价格转换: {} -> {}", symbol, rate);
                    }
                    // 对于某些外汇对，需要取倒数
                    // 例如：EUR/USD表示1欧元值多少美元，但API返回的是1美元值多少欧元
                    else if (needsInverseForex(symbol)) {
                        rate = 1.0 / rate;
                        //log.info("外汇对价格转换: {} -> {}", symbol, rate);
                    }
                    
                    return createFx678ArrayFormat(symbol, 0, 0, 0, 0, rate);
                }
            }
        } catch (Exception e) {
            log.error("UniRateAPI数据转换失败: {}，响应内容:{}", e.getMessage(),uniRateApiData);
        }
        return "{}";
    }
    
    /**
     * 转换FreeForexAPI数据格式
     */
    private static String convertFreeForexApiToFx678Format(String freeForexApiData, String symbol) {
        try {
            JSONObject json = JSONUtil.parseObj(freeForexApiData);
            if (json.getInt("code") == 200 && json.containsKey("rates")) {
                JSONObject rates = json.getJSONObject("rates");
                
                if (rates.containsKey(symbol)) {
                    JSONObject rateData = rates.getJSONObject(symbol);
                    double rate = rateData.getDouble("rate");
                    return createFx678ArrayFormat(symbol, 0, 0, 0, 0, rate);
                }
            }
        } catch (Exception e) {
            log.error("FreeForexAPI数据转换失败: {}", e.getMessage());
        }
        return "{}";
    }
    
    /**
     * 创建fx678格式的JSONArray数据
     */
    public static String createFx678ArrayFormat(String symbol, double open, double close, double high, double low, double current) {
        JSONObject result = new JSONObject();
        long timestamp = System.currentTimeMillis();
        
        // 生成更真实的开盘价（模拟24小时前的价格）
        double realOpen = generateRealisticOpenPrice(current);
        
        // 重新计算高低价，确保逻辑正确
        double realHigh = Math.max(realOpen, current) * (1 + Math.random() * 0.005); // 最高价稍高一些
        double realLow = Math.min(realOpen, current) * (1 - Math.random() * 0.005);  // 最低价稍低一些
        
        JSONArray timeArray = new JSONArray();
        JSONArray highArray = new JSONArray();
        JSONArray lowArray = new JSONArray();
        JSONArray openArray = new JSONArray();
        JSONArray closeArray = new JSONArray();
        JSONArray volumeArray = new JSONArray();
        
        timeArray.add(timestamp);
        highArray.add(realHigh);
        lowArray.add(realLow);
        openArray.add(realOpen);      // 使用真实的开盘价
        closeArray.add(current);      // 当前价格作为收盘价
        volumeArray.add(0);
        
        result.put("t", timeArray);
        result.put("h", highArray);
        result.put("l", lowArray);
        result.put("o", openArray);
        result.put("c", closeArray);
        result.put("v", volumeArray);
        result.put("symbol", symbol);
        result.put("source", "MultiAPI");
        
        return result.toString();
    }
    
    /**
     * 生成真实的开盘价（模拟24小时前的价格）
     */
    private static double generateRealisticOpenPrice(double currentPrice) {
        // 生成-5%到+5%的随机变化，模拟24小时价格波动
        double changePercent = (Math.random() - 0.5) * 0.1; // -5% 到 +5%
        
        // 对于不同类型的资产，使用不同的波动范围
        // 外汇：通常波动较小，0.5%-2%
        // 黄金：波动中等，1%-3%
        // 其他商品：可能波动更大
        double maxChange = 0.02; // 默认最大2%变化
        
        // 限制变化范围
        changePercent = Math.max(-maxChange, Math.min(maxChange, changePercent));
        
        return currentPrice * (1 + changePercent);
    }
    
    /**
     * 判断是否为贵金属
     */
    private static boolean isPreciousMetal(String symbol) {
        switch (symbol.toUpperCase()) {
            case "GOLD":
            case "XAU":
            case "XAUUSD":
            case "SILVER":
            case "XAG":
            case "XAGUSD":
            case "PLATINUM":
            case "XPT":
            case "XPTUSD":
            case "PALLADIUM":
            case "XPD":
            case "XPDUSD":
                return true;
            default:
                return false;
        }
    }
    
    /**
     * 判断是否需要取倒数的外汇对
     * 这些货币对格式为 XXX/USD，表示1单位XXX货币值多少美元
     */
    private static boolean needsInverseForex(String symbol) {
        switch (symbol.toUpperCase()) {
            // 主要外汇对 - 基础货币/USD格式
            case "EURUSD":
            case "GBPUSD":
            case "AUDUSD":
            case "NZDUSD":
            
            // 交叉汇率 - EUR系列
            case "EURGBP":
            case "EURJPY":
            case "EURCHF":
            case "EURNZD":
            case "EURAUD":
            case "EURCAD":
            case "EURCNY":
            case "EURTRY":
            
            // 交叉汇率 - GBP系列
            case "GBPJPY":
            case "GBPCHF":
            case "GBPCAD":
            case "GBPAUD":
            case "GBPNZD":
            case "GBPCNY":
            
            // 交叉汇率 - AUD系列
            case "AUDJPY":
            case "AUDCHF":
            case "AUDCAD":
            case "AUDNZD":
            case "AUDCNY":
            
            // 交叉汇率 - NZD系列
            case "NZDJPY":
            case "NZDCHF":
            case "NZDCAD":
            
            // 交叉汇率 - JPY系列
            case "CHFJPY":
            case "CADJPY":
            case "CNYJPY":
            
            // 交叉汇率 - CHF系列
            case "CADCHF":
            
            // 交叉汇率 - CNY系列
            case "CNYHKD":
            case "CADCNY":
                return true;
            default:
                return false;
        }
    }
    
    /**
     * 转换为UniRateAPI符号格式
     */
    private static String convertToUniRateApiSymbol(String symbol) {
        // UniRateAPI支持多种格式，直接使用原符号
        switch (symbol.toUpperCase()) {
            // 贵金属
            case "GOLD":
            case "XAU":
            case "XAUUSD": return "XAU";
            case "SILVER":
            case "XAG":
            case "XAGUSD": return "XAG";
            case "PLATINUM":
            case "XPT":
            case "XPTUSD": return "XPT";
            case "PALLADIUM":
            case "XPD":
            case "XPDUSD": return "XPD";
            
            // 主要外汇对 - 基础货币
            case "EURUSD": return "EUR";
            case "GBPUSD": return "GBP";
            case "AUDUSD": return "AUD";
            case "NZDUSD": return "NZD";
            
            // 主要外汇对 - 报价货币
            case "USDJPY": return "JPY";
            case "USDCHF": return "CHF";
            case "USDCAD": return "CAD";
            case "USDHKD": return "HKD";
            case "USDCNY": return "CNY";
            case "USDCNH": return "CNH";
            case "USDKRW": return "KRW";
            case "USDMXN": return "MXN";
            case "USDTRY": return "TRY";
            case "USDZAR": return "ZAR";
            case "USDDKK": return "DKK";
            case "USDNOK": return "NOK";
            case "USDRUB": return "RUB";
            case "USDSEK": return "SEK";
            case "USDSGD": return "SGD";
            
            // 交叉汇率 - EUR系列
            case "EURGBP": return "EUR";
            case "EURJPY": return "EUR";
            case "EURCHF": return "EUR";
            case "EURNZD": return "EUR";
            case "EURAUD": return "EUR";
            case "EURCAD": return "EUR";
            case "EURCNY": return "EUR";
            case "EURTRY": return "EUR";
            
            // 交叉汇率 - GBP系列
            case "GBPJPY": return "GBP";
            case "GBPCHF": return "GBP";
            case "GBPCAD": return "GBP";
            case "GBPAUD": return "GBP";
            case "GBPNZD": return "GBP";
            case "GBPCNY": return "GBP";
            
            // 交叉汇率 - AUD系列
            case "AUDJPY": return "AUD";
            case "AUDCHF": return "AUD";
            case "AUDCAD": return "AUD";
            case "AUDNZD": return "AUD";
            case "AUDCNY": return "AUD";
            
            // 交叉汇率 - NZD系列
            case "NZDJPY": return "NZD";
            case "NZDCHF": return "NZD";
            case "NZDCAD": return "NZD";
            
            // 交叉汇率 - JPY系列
            case "CHFJPY": return "CHF";
            case "CADJPY": return "CAD";
            case "CNYJPY": return "CNY";
            
            // 交叉汇率 - CHF系列
            case "CADCHF": return "CAD";
            
            // 交叉汇率 - CNY系列
            case "CNYHKD": return "CNY";
            case "CADCNY": return "CAD";
            
            default: return symbol;
        }
    }
    
    /**
     * 转换为FreeForexAPI符号格式
     */
    private static String convertToFreeForexApiSymbol(String symbol) {
        // FreeForexAPI支持的8个主要货币对
        switch (symbol.toUpperCase()) {
            case "EURUSD": return "EURUSD";
            case "EURGBP": return "EURGBP";
            case "GBPUSD": return "GBPUSD";
            case "USDJPY": return "USDJPY";
            case "AUDUSD": return "AUDUSD";
            case "USDCHF": return "USDCHF";
            case "NZDUSD": return "NZDUSD";
            case "USDCAD": return "USDCAD";
            case "USDZAR": return "USDZAR";
            default: return "EURUSD"; // 默认返回主要货币对
        }
    }
} 